package ic

import (
	"fmt"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"os"
	"path/filepath"
	"strings"

	_ "golang.org/x/image/bmp"
	_ "golang.org/x/image/tiff"
)

// Converter 图像转换器接口
type Converter interface {
	// 支持的格式名称
	SupportedFormat() string
	// 文件扩展名
	FileExtension() string
	// 编码图像
	Encode(img image.Image, options ...Options) ([]byte, error)
	// 解码图像（可选，用于支持该格式作为输入）
	Decode(data []byte) (image.Image, error)
	// MIME类型
	MimeType() string
}

// 内置转换器注册表
var converters = map[string]Converter{
	"webp": &WebPConverter{},
	"avif": &AVIFConverter{},
	"jpeg": &JPEGConverter{},
	"jpg":  &JPEGConverter{},
	"png":  &PNGConverter{},
	"gif":  &GIFConverter{},
	"bmp":  &BMPConverter{},
	"tiff": &TIFFConverter{},
	"tif":  &TIFFConverter{},
}

// GetConverter 获取指定格式的转换器
func GetConverter(format string) (Converter, error) {
	conv, exists := converters[strings.ToLower(format)]
	if !exists {
		return nil, fmt.Errorf("不支持的格式: %s", format)
	}
	return conv, nil
}

// ListSupportedFormats 列出所有支持的格式
func ListSupportedFormats() []string {
	formats := make([]string, 0, len(converters))
	seen := make(map[string]bool)

	for format := range converters {
		if !seen[format] {
			formats = append(formats, format)
			seen[format] = true
		}
	}
	return formats
}

// LoadImageFromFile 从文件加载图像
func LoadImageFromFile(filePath string) (image.Image, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	img, _, err := image.Decode(file)
	return img, err
}

// EnsureDir 确保目录存在
func EnsureDir(dirPath string) error {
	return os.MkdirAll(dirPath, 0755)
}

// Convert 转换单个图像文件
func Convert(inputPath, outputPath string, options ...Options) error {
	// 从输出路径推断目标格式
	ext := strings.ToLower(filepath.Ext(outputPath))
	if ext == "" {
		return fmt.Errorf("无法从输出路径确定目标格式")
	}

	// 去掉点号
	format := strings.TrimPrefix(ext, ".")

	return ConvertTo(inputPath, outputPath, format, options...)
}

// ConvertTo 转换单个图像文件到指定格式
func ConvertTo(inputPath, outputPath, targetFormat string, options ...Options) error {
	// 加载图像
	img, err := LoadImageFromFile(inputPath)
	if err != nil {
		return fmt.Errorf("加载图像失败: %v", err)
	}

	// 获取转换器
	conv, err := GetConverter(targetFormat)
	if err != nil {
		return err
	}

	// 编码
	data, err := conv.Encode(img, options...)
	if err != nil {
		return err
	}

	// 确保输出目录存在
	if err := EnsureDir(filepath.Dir(outputPath)); err != nil {
		return err
	}

	// 保存文件
	return os.WriteFile(outputPath, data, 0644)
}

// ConvertBytes 转换图像数据
func ConvertBytes(imgData []byte, targetFormat string, options ...Options) ([]byte, error) {
	// 解码图像
	img, _, err := image.Decode(strings.NewReader(string(imgData)))
	if err != nil {
		return nil, fmt.Errorf("解码图像失败: %v", err)
	}

	// 获取转换器
	conv, err := GetConverter(targetFormat)
	if err != nil {
		return nil, err
	}

	// 编码
	return conv.Encode(img, options...)
}

// ConvertImage 转换image.Image对象
func ConvertImage(img image.Image, targetFormat string, options ...Options) ([]byte, error) {
	// 获取转换器
	conv, err := GetConverter(targetFormat)
	if err != nil {
		return nil, err
	}

	// 编码
	return conv.Encode(img, options...)
}

// GetConverterInfo 获取转换器信息
func GetConverterInfo(format string) (Converter, error) {
	return GetConverter(format)
}

// ValidateFormat 验证格式是否支持
func ValidateFormat(format string) bool {
	_, err := GetConverter(format)
	return err == nil
}

// GetFormatByExtension 根据文件扩展名获取格式
func GetFormatByExtension(filePath string) (string, error) {
	ext := strings.ToLower(filepath.Ext(filePath))
	if ext == "" {
		return "", fmt.Errorf("文件没有扩展名")
	}

	format := strings.TrimPrefix(ext, ".")
	if ValidateFormat(format) {
		return format, nil
	}

	return "", fmt.Errorf("不支持的文件格式: %s", ext)
}
